package com.kuizii.base.aspect;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.kuizii.base.annotaion.AuditLog;
import com.kuizii.base.domain.BaseResponse;
import com.kuizii.base.domain.OptStatus;

import com.kuizii.base.util.IpUtil;
import com.kuizii.base.util.log.ILogWriter;
import com.kuizii.base.util.log.LogEntity;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class AuditLogAspect {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired
    ILogWriter logWriter;

    static ExecutorService executorService = new ThreadPoolExecutor(0, 5,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue<Runnable>(), new ThreadFactoryBuilder().setNameFormat("logs").build());


    @Pointcut("@annotation(com.kuizii.base.annotaion.AuditLog)")
    public void logPointCut() {

    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        AuditLog syslog = method.getAnnotation(AuditLog.class);

        LogEntity logEntity = new LogEntity();
        //获取方法执行前时间
        long beginTime = System.currentTimeMillis();
        logEntity.setBeginTime(LocalDateTime.now().format(formatter));
        Object result = joinPoint.proceed();
        //获取session中的用户
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();


        if (request != null) {
            //获取请求的ip
            String ip = IpUtil.getIpAddress(request);
            logEntity.setIp(ip);
            logEntity.setApplicationId(request.getHeader("token"));
            logEntity.setToken(request.getHeader("applicationid"));
//             logEntity.setHeaders(request.);
//             logEntity.setParams(WebUtils.getRequestContent(request));
            //获取请求URL
             logEntity.setRequestUri(request.getRequestURI());
        }
        //获取执行的类名
        logEntity.setMethodClass(joinPoint.getTarget().getClass().getName());
        //获取执行的方法名
        logEntity.setMethodName(joinPoint.getSignature().getName());

        logEntity.setType(syslog.logType());
        if (result instanceof BaseResponse) {
            BaseResponse res = (BaseResponse) result;
            //设置操作信息
            logEntity.setOptStatus(res.getOptStatus());
            logEntity.setActionType(syslog.actionType());
            logEntity.setDescription(syslog.description());
            logEntity.setMessage(res.getMessage());
            logEntity.setDetailMsg(res.getDetailMsg());
        } else {
            logEntity.setOptStatus(OptStatus.OK);
        }
        logEntity.setTermType("1");

        logEntity.setEndTime(LocalDateTime.now().format(formatter));
        logEntity.setTotalTime(System.currentTimeMillis() - beginTime + "");
        executorService.execute(() -> {
            logWriter.writer(logEntity);
        });
        return result;

    }


}
